/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"

#include <assert.h>
#include <stddef.h>
#include <string.h>

#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>

#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/surface/validate_metadata.h"
#include "src/core/lib/transport/http2_errors.h"

#if __cplusplus > 201103L
#define GRPC_HPACK_CONSTEXPR_FN constexpr
#define GRPC_HPACK_CONSTEXPR_VALUE constexpr
#else
#define GRPC_HPACK_CONSTEXPR_FN
#define GRPC_HPACK_CONSTEXPR_VALUE const
#endif

namespace grpc_core {

DebugOnlyTraceFlag grpc_trace_chttp2_hpack_parser(false, "chttp2_hpack_parser");

/* How parsing works:

   The parser object keeps track of a function pointer which represents the
   current parse state.

   Each time new bytes are presented, we call into the current state, which
   recursively parses until all bytes in the given chunk are exhausted.

   The parse state that terminates then saves its function pointer to be the
   current state so that it can resume when more bytes are available.

   It's expected that most optimizing compilers will turn this code into
   a set of indirect jumps, and so not waste stack space. */

/* state table for huffman decoding: given a state, gives an index/16 into
   next_sub_tbl. Taking that index and adding the value of the nibble being
   considered returns the next state.

   generated by gen_hpack_tables.c */
static const uint8_t next_tbl[256] = {
    0,  1,  2,  3,  4,  1,  2, 5,  6,  1, 7,  8,  1,  3,  3,  9,  10, 11, 1,  1,
    1,  12, 1,  2,  13, 1,  1, 1,  1,  1, 1,  1,  1,  1,  1,  1,  1,  1,  1,  2,
    14, 1,  15, 16, 1,  17, 1, 15, 2,  7, 3,  18, 19, 1,  1,  1,  1,  20, 1,  1,
    1,  1,  1,  1,  1,  1,  1, 1,  15, 2, 2,  7,  21, 1,  22, 1,  1,  1,  1,  1,
    1,  1,  1,  15, 2,  2,  2, 2,  2,  2, 23, 24, 25, 1,  1,  1,  1,  2,  2,  2,
    26, 3,  3,  27, 10, 28, 1, 1,  1,  1, 1,  1,  2,  3,  29, 10, 30, 1,  1,  1,
    1,  1,  1,  1,  1,  1,  1, 1,  1,  1, 1,  31, 1,  1,  1,  1,  1,  1,  1,  2,
    2,  2,  2,  2,  2,  2,  2, 32, 1,  1, 15, 33, 1,  34, 35, 9,  36, 1,  1,  1,
    1,  1,  1,  1,  37, 1,  1, 1,  1,  1, 1,  2,  2,  2,  2,  2,  2,  2,  26, 9,
    38, 1,  1,  1,  1,  1,  1, 1,  15, 2, 2,  2,  2,  26, 3,  3,  39, 1,  1,  1,
    1,  1,  1,  1,  1,  1,  1, 1,  2,  2, 2,  2,  2,  2,  7,  3,  3,  3,  40, 2,
    41, 1,  1,  1,  42, 43, 1, 1,  44, 1, 1,  1,  1,  15, 2,  2,  2,  2,  2,  2,
    3,  3,  3,  45, 46, 1,  1, 2,  2,  2, 35, 3,  3,  18, 47, 2,
};

/* next state, based upon current state and the current nibble: see above.
   generated by gen_hpack_tables.c */
static const int16_t next_sub_tbl[48 * 16] = {
    1,   204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
    218, 2,   6,   10,  13,  14,  15,  16,  17,  2,   6,   10,  13,  14,  15,
    16,  17,  3,   7,   11,  24,  3,   7,   11,  24,  3,   7,   11,  24,  3,
    7,   11,  24,  4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,
    4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   5,
    199, 200, 201, 202, 203, 4,   8,   4,   8,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   9,   133, 134, 135, 136, 137, 138, 139, 140,
    141, 142, 143, 144, 145, 146, 147, 3,   7,   11,  24,  3,   7,   11,  24,
    4,   8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   0,   12,  132, 4,   8,   4,   8,   4,   8,
    4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   0,   0,   18,  19,  20,  21,  4,   8,   4,
    8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   22,  23,  91,  25,  26,
    27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  3,
    7,   11,  24,  3,   7,   11,  24,  0,   0,   0,   0,   0,   41,  42,  43,
    2,   6,   10,  13,  14,  15,  16,  17,  3,   7,   11,  24,  3,   7,   11,
    24,  4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,
    44,  45,  2,   6,   10,  13,  14,  15,  16,  17,  46,  47,  48,  49,  50,
    51,  52,  57,  4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   53,  54,  55,  56,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
    68,  69,  70,  71,  72,  74,  0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   73,  75,  76,  77,  78,  79,  80,  81,  82,
    83,  84,  85,  86,  87,  88,  89,  90,  3,   7,   11,  24,  3,   7,   11,
    24,  3,   7,   11,  24,  0,   0,   0,   0,   3,   7,   11,  24,  3,   7,
    11,  24,  4,   8,   4,   8,   0,   0,   0,   92,  0,   0,   0,   93,  94,
    95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 3,   7,   11,  24,
    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,
    8,   4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   0,   106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 4,
    8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,
    0,   117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
    131, 2,   6,   10,  13,  14,  15,  16,  17,  4,   8,   4,   8,   4,   8,
    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   148,
    149, 150, 151, 3,   7,   11,  24,  4,   8,   4,   8,   0,   0,   0,   0,
    0,   0,   152, 153, 3,   7,   11,  24,  3,   7,   11,  24,  3,   7,   11,
    24,  154, 155, 156, 164, 3,   7,   11,  24,  3,   7,   11,  24,  3,   7,
    11,  24,  4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    157, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 171, 172,
    173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
    188, 189, 190, 191, 192, 193, 194, 195, 196, 4,   8,   4,   8,   4,   8,
    4,   8,   4,   8,   4,   8,   4,   8,   197, 198, 4,   8,   4,   8,   4,
    8,   4,   8,   0,   0,   0,   0,   0,   0,   219, 220, 3,   7,   11,  24,
    4,   8,   4,   8,   4,   8,   0,   0,   221, 222, 223, 224, 3,   7,   11,
    24,  3,   7,   11,  24,  4,   8,   4,   8,   4,   8,   225, 228, 4,   8,
    4,   8,   4,   8,   0,   0,   0,   0,   0,   0,   0,   0,   226, 227, 229,
    230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
    4,   8,   4,   8,   4,   8,   4,   8,   4,   8,   0,   0,   0,   0,   0,
    0,   0,   0,   0,   0,   0,   0,   245, 246, 247, 248, 249, 250, 251, 252,
    253, 254, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    0,   0,   255,
};

/* emission table: indexed like next_tbl, ultimately gives the byte to be
   emitted, or -1 for no byte, or 256 for end of stream

   generated by gen_hpack_tables.c */
static const uint16_t emit_tbl[256] = {
    0,   1,   2,   3,   4,   5,   6,   7,   0,   8,   9,   10,  11,  12,  13,
    14,  15,  16,  17,  18,  19,  20,  21,  22,  0,   23,  24,  25,  26,  27,
    28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
    43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  0,   55,  56,
    57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  0,
    71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,
    86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100,
    101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
    116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
    131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
    146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 0,
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
    0,   175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
    189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
    204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
    219, 220, 221, 0,   222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
    233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
    248,
};

/* generated by gen_hpack_tables.c */
static const int16_t emit_sub_tbl[249 * 16] = {
    -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
    -1,  48,  48,  48,  48,  48,  48,  48,  48,  49,  49,  49,  49,  49,  49,
    49,  49,  48,  48,  48,  48,  49,  49,  49,  49,  50,  50,  50,  50,  97,
    97,  97,  97,  48,  48,  49,  49,  50,  50,  97,  97,  99,  99,  101, 101,
    105, 105, 111, 111, 48,  49,  50,  97,  99,  101, 105, 111, 115, 116, -1,
    -1,  -1,  -1,  -1,  -1,  32,  32,  32,  32,  32,  32,  32,  32,  37,  37,
    37,  37,  37,  37,  37,  37,  99,  99,  99,  99,  101, 101, 101, 101, 105,
    105, 105, 105, 111, 111, 111, 111, 115, 115, 116, 116, 32,  37,  45,  46,
    47,  51,  52,  53,  54,  55,  56,  57,  61,  61,  61,  61,  61,  61,  61,
    61,  65,  65,  65,  65,  65,  65,  65,  65,  115, 115, 115, 115, 116, 116,
    116, 116, 32,  32,  37,  37,  45,  45,  46,  46,  61,  65,  95,  98,  100,
    102, 103, 104, 108, 109, 110, 112, 114, 117, -1,  -1,  58,  58,  58,  58,
    58,  58,  58,  58,  66,  66,  66,  66,  66,  66,  66,  66,  47,  47,  51,
    51,  52,  52,  53,  53,  54,  54,  55,  55,  56,  56,  57,  57,  61,  61,
    65,  65,  95,  95,  98,  98,  100, 100, 102, 102, 103, 103, 104, 104, 108,
    108, 109, 109, 110, 110, 112, 112, 114, 114, 117, 117, 58,  66,  67,  68,
    69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
    84,  85,  86,  87,  89,  106, 107, 113, 118, 119, 120, 121, 122, -1,  -1,
    -1,  -1,  38,  38,  38,  38,  38,  38,  38,  38,  42,  42,  42,  42,  42,
    42,  42,  42,  44,  44,  44,  44,  44,  44,  44,  44,  59,  59,  59,  59,
    59,  59,  59,  59,  88,  88,  88,  88,  88,  88,  88,  88,  90,  90,  90,
    90,  90,  90,  90,  90,  33,  33,  34,  34,  40,  40,  41,  41,  63,  63,
    39,  43,  124, -1,  -1,  -1,  35,  35,  35,  35,  35,  35,  35,  35,  62,
    62,  62,  62,  62,  62,  62,  62,  0,   0,   0,   0,   36,  36,  36,  36,
    64,  64,  64,  64,  91,  91,  91,  91,  69,  69,  69,  69,  69,  69,  69,
    69,  70,  70,  70,  70,  70,  70,  70,  70,  71,  71,  71,  71,  71,  71,
    71,  71,  72,  72,  72,  72,  72,  72,  72,  72,  73,  73,  73,  73,  73,
    73,  73,  73,  74,  74,  74,  74,  74,  74,  74,  74,  75,  75,  75,  75,
    75,  75,  75,  75,  76,  76,  76,  76,  76,  76,  76,  76,  77,  77,  77,
    77,  77,  77,  77,  77,  78,  78,  78,  78,  78,  78,  78,  78,  79,  79,
    79,  79,  79,  79,  79,  79,  80,  80,  80,  80,  80,  80,  80,  80,  81,
    81,  81,  81,  81,  81,  81,  81,  82,  82,  82,  82,  82,  82,  82,  82,
    83,  83,  83,  83,  83,  83,  83,  83,  84,  84,  84,  84,  84,  84,  84,
    84,  85,  85,  85,  85,  85,  85,  85,  85,  86,  86,  86,  86,  86,  86,
    86,  86,  87,  87,  87,  87,  87,  87,  87,  87,  89,  89,  89,  89,  89,
    89,  89,  89,  106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107,
    107, 107, 107, 107, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118,
    118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 120, 120,
    120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 122,
    122, 122, 122, 122, 122, 122, 122, 38,  38,  38,  38,  42,  42,  42,  42,
    44,  44,  44,  44,  59,  59,  59,  59,  88,  88,  88,  88,  90,  90,  90,
    90,  33,  34,  40,  41,  63,  -1,  -1,  -1,  39,  39,  39,  39,  39,  39,
    39,  39,  43,  43,  43,  43,  43,  43,  43,  43,  124, 124, 124, 124, 124,
    124, 124, 124, 35,  35,  35,  35,  62,  62,  62,  62,  0,   0,   36,  36,
    64,  64,  91,  91,  93,  93,  126, 126, 94,  125, -1,  -1,  60,  60,  60,
    60,  60,  60,  60,  60,  96,  96,  96,  96,  96,  96,  96,  96,  123, 123,
    123, 123, 123, 123, 123, 123, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  92,
    92,  92,  92,  92,  92,  92,  92,  195, 195, 195, 195, 195, 195, 195, 195,
    208, 208, 208, 208, 208, 208, 208, 208, 128, 128, 128, 128, 130, 130, 130,
    130, 131, 131, 131, 131, 162, 162, 162, 162, 184, 184, 184, 184, 194, 194,
    194, 194, 224, 224, 224, 224, 226, 226, 226, 226, 153, 153, 161, 161, 167,
    167, 172, 172, 176, 176, 177, 177, 179, 179, 209, 209, 216, 216, 217, 217,
    227, 227, 229, 229, 230, 230, 129, 132, 133, 134, 136, 146, 154, 156, 160,
    163, 164, 169, 170, 173, 178, 181, 185, 186, 187, 189, 190, 196, 198, 228,
    232, 233, -1,  -1,  -1,  -1,  1,   1,   1,   1,   1,   1,   1,   1,   135,
    135, 135, 135, 135, 135, 135, 135, 137, 137, 137, 137, 137, 137, 137, 137,
    138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139,
    139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141,
    141, 141, 143, 143, 143, 143, 143, 143, 143, 143, 147, 147, 147, 147, 147,
    147, 147, 147, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150,
    150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152,
    152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 157, 157,
    157, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 165,
    165, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166,
    168, 168, 168, 168, 168, 168, 168, 168, 174, 174, 174, 174, 174, 174, 174,
    174, 175, 175, 175, 175, 175, 175, 175, 175, 180, 180, 180, 180, 180, 180,
    180, 180, 182, 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183,
    183, 183, 183, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191,
    191, 191, 191, 191, 197, 197, 197, 197, 197, 197, 197, 197, 231, 231, 231,
    231, 231, 231, 231, 231, 239, 239, 239, 239, 239, 239, 239, 239, 9,   9,
    9,   9,   142, 142, 142, 142, 144, 144, 144, 144, 145, 145, 145, 145, 148,
    148, 148, 148, 159, 159, 159, 159, 171, 171, 171, 171, 206, 206, 206, 206,
    215, 215, 215, 215, 225, 225, 225, 225, 236, 236, 236, 236, 237, 237, 237,
    237, 199, 199, 207, 207, 234, 234, 235, 235, 192, 193, 200, 201, 202, 205,
    210, 213, 218, 219, 238, 240, 242, 243, 255, -1,  203, 203, 203, 203, 203,
    203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 211, 211, 211, 211,
    211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 214, 214, 214,
    214, 214, 214, 214, 214, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222,
    222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 241,
    241, 241, 241, 241, 241, 241, 241, 244, 244, 244, 244, 244, 244, 244, 244,
    245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246,
    246, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248,
    248, 248, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251,
    251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253,
    253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 2,   2,   2,
    2,   3,   3,   3,   3,   4,   4,   4,   4,   5,   5,   5,   5,   6,   6,
    6,   6,   7,   7,   7,   7,   8,   8,   8,   8,   11,  11,  11,  11,  12,
    12,  12,  12,  14,  14,  14,  14,  15,  15,  15,  15,  16,  16,  16,  16,
    17,  17,  17,  17,  18,  18,  18,  18,  19,  19,  19,  19,  20,  20,  20,
    20,  21,  21,  21,  21,  23,  23,  23,  23,  24,  24,  24,  24,  25,  25,
    25,  25,  26,  26,  26,  26,  27,  27,  27,  27,  28,  28,  28,  28,  29,
    29,  29,  29,  30,  30,  30,  30,  31,  31,  31,  31,  127, 127, 127, 127,
    220, 220, 220, 220, 249, 249, 249, 249, 10,  13,  22,  256, 93,  93,  93,
    93,  126, 126, 126, 126, 94,  94,  125, 125, 60,  96,  123, -1,  92,  195,
    208, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  128,
    128, 128, 128, 128, 128, 128, 128, 130, 130, 130, 130, 130, 130, 130, 130,
    131, 131, 131, 131, 131, 131, 131, 131, 162, 162, 162, 162, 162, 162, 162,
    162, 184, 184, 184, 184, 184, 184, 184, 184, 194, 194, 194, 194, 194, 194,
    194, 194, 224, 224, 224, 224, 224, 224, 224, 224, 226, 226, 226, 226, 226,
    226, 226, 226, 153, 153, 153, 153, 161, 161, 161, 161, 167, 167, 167, 167,
    172, 172, 172, 172, 176, 176, 176, 176, 177, 177, 177, 177, 179, 179, 179,
    179, 209, 209, 209, 209, 216, 216, 216, 216, 217, 217, 217, 217, 227, 227,
    227, 227, 229, 229, 229, 229, 230, 230, 230, 230, 129, 129, 132, 132, 133,
    133, 134, 134, 136, 136, 146, 146, 154, 154, 156, 156, 160, 160, 163, 163,
    164, 164, 169, 169, 170, 170, 173, 173, 178, 178, 181, 181, 185, 185, 186,
    186, 187, 187, 189, 189, 190, 190, 196, 196, 198, 198, 228, 228, 232, 232,
    233, 233, 1,   135, 137, 138, 139, 140, 141, 143, 147, 149, 150, 151, 152,
    155, 157, 158, 165, 166, 168, 174, 175, 180, 182, 183, 188, 191, 197, 231,
    239, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  9,   9,   9,
    9,   9,   9,   9,   9,   142, 142, 142, 142, 142, 142, 142, 142, 144, 144,
    144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 148,
    148, 148, 148, 148, 148, 148, 148, 159, 159, 159, 159, 159, 159, 159, 159,
    171, 171, 171, 171, 171, 171, 171, 171, 206, 206, 206, 206, 206, 206, 206,
    206, 215, 215, 215, 215, 215, 215, 215, 215, 225, 225, 225, 225, 225, 225,
    225, 225, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237,
    237, 237, 237, 199, 199, 199, 199, 207, 207, 207, 207, 234, 234, 234, 234,
    235, 235, 235, 235, 192, 192, 193, 193, 200, 200, 201, 201, 202, 202, 205,
    205, 210, 210, 213, 213, 218, 218, 219, 219, 238, 238, 240, 240, 242, 242,
    243, 243, 255, 255, 203, 204, 211, 212, 214, 221, 222, 223, 241, 244, 245,
    246, 247, 248, 250, 251, 252, 253, 254, -1,  -1,  -1,  -1,  -1,  -1,  -1,
    -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  2,   2,   2,   2,   2,   2,   2,
    2,   3,   3,   3,   3,   3,   3,   3,   3,   4,   4,   4,   4,   4,   4,
    4,   4,   5,   5,   5,   5,   5,   5,   5,   5,   6,   6,   6,   6,   6,
    6,   6,   6,   7,   7,   7,   7,   7,   7,   7,   7,   8,   8,   8,   8,
    8,   8,   8,   8,   11,  11,  11,  11,  11,  11,  11,  11,  12,  12,  12,
    12,  12,  12,  12,  12,  14,  14,  14,  14,  14,  14,  14,  14,  15,  15,
    15,  15,  15,  15,  15,  15,  16,  16,  16,  16,  16,  16,  16,  16,  17,
    17,  17,  17,  17,  17,  17,  17,  18,  18,  18,  18,  18,  18,  18,  18,
    19,  19,  19,  19,  19,  19,  19,  19,  20,  20,  20,  20,  20,  20,  20,
    20,  21,  21,  21,  21,  21,  21,  21,  21,  23,  23,  23,  23,  23,  23,
    23,  23,  24,  24,  24,  24,  24,  24,  24,  24,  25,  25,  25,  25,  25,
    25,  25,  25,  26,  26,  26,  26,  26,  26,  26,  26,  27,  27,  27,  27,
    27,  27,  27,  27,  28,  28,  28,  28,  28,  28,  28,  28,  29,  29,  29,
    29,  29,  29,  29,  29,  30,  30,  30,  30,  30,  30,  30,  30,  31,  31,
    31,  31,  31,  31,  31,  31,  127, 127, 127, 127, 127, 127, 127, 127, 220,
    220, 220, 220, 220, 220, 220, 220, 249, 249, 249, 249, 249, 249, 249, 249,
    10,  10,  13,  13,  22,  22,  256, 256, 67,  67,  67,  67,  67,  67,  67,
    67,  68,  68,  68,  68,  68,  68,  68,  68,  95,  95,  95,  95,  95,  95,
    95,  95,  98,  98,  98,  98,  98,  98,  98,  98,  100, 100, 100, 100, 100,
    100, 100, 100, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103,
    103, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, 104, 108, 108, 108,
    108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 110, 110,
    110, 110, 110, 110, 110, 110, 112, 112, 112, 112, 112, 112, 112, 112, 114,
    114, 114, 114, 114, 114, 114, 114, 117, 117, 117, 117, 117, 117, 117, 117,
    58,  58,  58,  58,  66,  66,  66,  66,  67,  67,  67,  67,  68,  68,  68,
    68,  69,  69,  69,  69,  70,  70,  70,  70,  71,  71,  71,  71,  72,  72,
    72,  72,  73,  73,  73,  73,  74,  74,  74,  74,  75,  75,  75,  75,  76,
    76,  76,  76,  77,  77,  77,  77,  78,  78,  78,  78,  79,  79,  79,  79,
    80,  80,  80,  80,  81,  81,  81,  81,  82,  82,  82,  82,  83,  83,  83,
    83,  84,  84,  84,  84,  85,  85,  85,  85,  86,  86,  86,  86,  87,  87,
    87,  87,  89,  89,  89,  89,  106, 106, 106, 106, 107, 107, 107, 107, 113,
    113, 113, 113, 118, 118, 118, 118, 119, 119, 119, 119, 120, 120, 120, 120,
    121, 121, 121, 121, 122, 122, 122, 122, 38,  38,  42,  42,  44,  44,  59,
    59,  88,  88,  90,  90,  -1,  -1,  -1,  -1,  33,  33,  33,  33,  33,  33,
    33,  33,  34,  34,  34,  34,  34,  34,  34,  34,  40,  40,  40,  40,  40,
    40,  40,  40,  41,  41,  41,  41,  41,  41,  41,  41,  63,  63,  63,  63,
    63,  63,  63,  63,  39,  39,  39,  39,  43,  43,  43,  43,  124, 124, 124,
    124, 35,  35,  62,  62,  0,   36,  64,  91,  93,  126, -1,  -1,  94,  94,
    94,  94,  94,  94,  94,  94,  125, 125, 125, 125, 125, 125, 125, 125, 60,
    60,  60,  60,  96,  96,  96,  96,  123, 123, 123, 123, -1,  -1,  -1,  -1,
    92,  92,  92,  92,  195, 195, 195, 195, 208, 208, 208, 208, 128, 128, 130,
    130, 131, 131, 162, 162, 184, 184, 194, 194, 224, 224, 226, 226, 153, 161,
    167, 172, 176, 177, 179, 209, 216, 217, 227, 229, 230, -1,  -1,  -1,  -1,
    -1,  -1,  -1,  129, 129, 129, 129, 129, 129, 129, 129, 132, 132, 132, 132,
    132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134,
    134, 134, 134, 134, 134, 136, 136, 136, 136, 136, 136, 136, 136, 146, 146,
    146, 146, 146, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, 156,
    156, 156, 156, 156, 156, 156, 156, 160, 160, 160, 160, 160, 160, 160, 160,
    163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164,
    164, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170,
    170, 170, 173, 173, 173, 173, 173, 173, 173, 173, 178, 178, 178, 178, 178,
    178, 178, 178, 181, 181, 181, 181, 181, 181, 181, 181, 185, 185, 185, 185,
    185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187,
    187, 187, 187, 187, 187, 189, 189, 189, 189, 189, 189, 189, 189, 190, 190,
    190, 190, 190, 190, 190, 190, 196, 196, 196, 196, 196, 196, 196, 196, 198,
    198, 198, 198, 198, 198, 198, 198, 228, 228, 228, 228, 228, 228, 228, 228,
    232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233,
    233, 1,   1,   1,   1,   135, 135, 135, 135, 137, 137, 137, 137, 138, 138,
    138, 138, 139, 139, 139, 139, 140, 140, 140, 140, 141, 141, 141, 141, 143,
    143, 143, 143, 147, 147, 147, 147, 149, 149, 149, 149, 150, 150, 150, 150,
    151, 151, 151, 151, 152, 152, 152, 152, 155, 155, 155, 155, 157, 157, 157,
    157, 158, 158, 158, 158, 165, 165, 165, 165, 166, 166, 166, 166, 168, 168,
    168, 168, 174, 174, 174, 174, 175, 175, 175, 175, 180, 180, 180, 180, 182,
    182, 182, 182, 183, 183, 183, 183, 188, 188, 188, 188, 191, 191, 191, 191,
    197, 197, 197, 197, 231, 231, 231, 231, 239, 239, 239, 239, 9,   9,   142,
    142, 144, 144, 145, 145, 148, 148, 159, 159, 171, 171, 206, 206, 215, 215,
    225, 225, 236, 236, 237, 237, 199, 207, 234, 235, 192, 192, 192, 192, 192,
    192, 192, 192, 193, 193, 193, 193, 193, 193, 193, 193, 200, 200, 200, 200,
    200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202,
    202, 202, 202, 202, 202, 205, 205, 205, 205, 205, 205, 205, 205, 210, 210,
    210, 210, 210, 210, 210, 210, 213, 213, 213, 213, 213, 213, 213, 213, 218,
    218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219,
    238, 238, 238, 238, 238, 238, 238, 238, 240, 240, 240, 240, 240, 240, 240,
    240, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243,
    243, 243, 255, 255, 255, 255, 255, 255, 255, 255, 203, 203, 203, 203, 204,
    204, 204, 204, 211, 211, 211, 211, 212, 212, 212, 212, 214, 214, 214, 214,
    221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 241, 241, 241,
    241, 244, 244, 244, 244, 245, 245, 245, 245, 246, 246, 246, 246, 247, 247,
    247, 247, 248, 248, 248, 248, 250, 250, 250, 250, 251, 251, 251, 251, 252,
    252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 2,   2,   3,   3,
    4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   11,  11,  12,  12,  14,
    14,  15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,
    23,  23,  24,  24,  25,  25,  26,  26,  27,  27,  28,  28,  29,  29,  30,
    30,  31,  31,  127, 127, 220, 220, 249, 249, -1,  -1,  10,  10,  10,  10,
    10,  10,  10,  10,  13,  13,  13,  13,  13,  13,  13,  13,  22,  22,  22,
    22,  22,  22,  22,  22,  256, 256, 256, 256, 256, 256, 256, 256, 45,  45,
    45,  45,  45,  45,  45,  45,  46,  46,  46,  46,  46,  46,  46,  46,  47,
    47,  47,  47,  47,  47,  47,  47,  51,  51,  51,  51,  51,  51,  51,  51,
    52,  52,  52,  52,  52,  52,  52,  52,  53,  53,  53,  53,  53,  53,  53,
    53,  54,  54,  54,  54,  54,  54,  54,  54,  55,  55,  55,  55,  55,  55,
    55,  55,  56,  56,  56,  56,  56,  56,  56,  56,  57,  57,  57,  57,  57,
    57,  57,  57,  50,  50,  50,  50,  50,  50,  50,  50,  97,  97,  97,  97,
    97,  97,  97,  97,  99,  99,  99,  99,  99,  99,  99,  99,  101, 101, 101,
    101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 105, 105, 105, 111, 111,
    111, 111, 111, 111, 111, 111, 115, 115, 115, 115, 115, 115, 115, 115, 116,
    116, 116, 116, 116, 116, 116, 116, 32,  32,  32,  32,  37,  37,  37,  37,
    45,  45,  45,  45,  46,  46,  46,  46,  47,  47,  47,  47,  51,  51,  51,
    51,  52,  52,  52,  52,  53,  53,  53,  53,  54,  54,  54,  54,  55,  55,
    55,  55,  56,  56,  56,  56,  57,  57,  57,  57,  61,  61,  61,  61,  65,
    65,  65,  65,  95,  95,  95,  95,  98,  98,  98,  98,  100, 100, 100, 100,
    102, 102, 102, 102, 103, 103, 103, 103, 104, 104, 104, 104, 108, 108, 108,
    108, 109, 109, 109, 109, 110, 110, 110, 110, 112, 112, 112, 112, 114, 114,
    114, 114, 117, 117, 117, 117, 58,  58,  66,  66,  67,  67,  68,  68,  69,
    69,  70,  70,  71,  71,  72,  72,  73,  73,  74,  74,  75,  75,  76,  76,
    77,  77,  78,  78,  79,  79,  80,  80,  81,  81,  82,  82,  83,  83,  84,
    84,  85,  85,  86,  86,  87,  87,  89,  89,  106, 106, 107, 107, 113, 113,
    118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 38,  42,  44,  59,  88,
    90,  -1,  -1,  33,  33,  33,  33,  34,  34,  34,  34,  40,  40,  40,  40,
    41,  41,  41,  41,  63,  63,  63,  63,  39,  39,  43,  43,  124, 124, 35,
    62,  -1,  -1,  -1,  -1,  0,   0,   0,   0,   0,   0,   0,   0,   36,  36,
    36,  36,  36,  36,  36,  36,  64,  64,  64,  64,  64,  64,  64,  64,  91,
    91,  91,  91,  91,  91,  91,  91,  93,  93,  93,  93,  93,  93,  93,  93,
    126, 126, 126, 126, 126, 126, 126, 126, 94,  94,  94,  94,  125, 125, 125,
    125, 60,  60,  96,  96,  123, 123, -1,  -1,  92,  92,  195, 195, 208, 208,
    128, 130, 131, 162, 184, 194, 224, 226, -1,  -1,  153, 153, 153, 153, 153,
    153, 153, 153, 161, 161, 161, 161, 161, 161, 161, 161, 167, 167, 167, 167,
    167, 167, 167, 167, 172, 172, 172, 172, 172, 172, 172, 172, 176, 176, 176,
    176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 179, 179,
    179, 179, 179, 179, 179, 179, 209, 209, 209, 209, 209, 209, 209, 209, 216,
    216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 217,
    227, 227, 227, 227, 227, 227, 227, 227, 229, 229, 229, 229, 229, 229, 229,
    229, 230, 230, 230, 230, 230, 230, 230, 230, 129, 129, 129, 129, 132, 132,
    132, 132, 133, 133, 133, 133, 134, 134, 134, 134, 136, 136, 136, 136, 146,
    146, 146, 146, 154, 154, 154, 154, 156, 156, 156, 156, 160, 160, 160, 160,
    163, 163, 163, 163, 164, 164, 164, 164, 169, 169, 169, 169, 170, 170, 170,
    170, 173, 173, 173, 173, 178, 178, 178, 178, 181, 181, 181, 181, 185, 185,
    185, 185, 186, 186, 186, 186, 187, 187, 187, 187, 189, 189, 189, 189, 190,
    190, 190, 190, 196, 196, 196, 196, 198, 198, 198, 198, 228, 228, 228, 228,
    232, 232, 232, 232, 233, 233, 233, 233, 1,   1,   135, 135, 137, 137, 138,
    138, 139, 139, 140, 140, 141, 141, 143, 143, 147, 147, 149, 149, 150, 150,
    151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 165, 165, 166, 166, 168,
    168, 174, 174, 175, 175, 180, 180, 182, 182, 183, 183, 188, 188, 191, 191,
    197, 197, 231, 231, 239, 239, 9,   142, 144, 145, 148, 159, 171, 206, 215,
    225, 236, 237, -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  199, 199,
    199, 199, 199, 199, 199, 199, 207, 207, 207, 207, 207, 207, 207, 207, 234,
    234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235,
    192, 192, 192, 192, 193, 193, 193, 193, 200, 200, 200, 200, 201, 201, 201,
    201, 202, 202, 202, 202, 205, 205, 205, 205, 210, 210, 210, 210, 213, 213,
    213, 213, 218, 218, 218, 218, 219, 219, 219, 219, 238, 238, 238, 238, 240,
    240, 240, 240, 242, 242, 242, 242, 243, 243, 243, 243, 255, 255, 255, 255,
    203, 203, 204, 204, 211, 211, 212, 212, 214, 214, 221, 221, 222, 222, 223,
    223, 241, 241, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 250, 250,
    251, 251, 252, 252, 253, 253, 254, 254, 2,   3,   4,   5,   6,   7,   8,
    11,  12,  14,  15,  16,  17,  18,  19,  20,  21,  23,  24,  25,  26,  27,
    28,  29,  30,  31,  127, 220, 249, -1,  10,  10,  10,  10,  13,  13,  13,
    13,  22,  22,  22,  22,  256, 256, 256, 256,
};

namespace {
// The alphabet used for base64 encoding binary metadata.
static constexpr char kBase64Alphabet[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

// An inverted table: for each value in kBase64Alphabet, table contains the
// index with which it's stored, so we can quickly invert the encoding without
// any complicated runtime logic.
struct Base64InverseTable {
  uint8_t table[256]{};
  GRPC_HPACK_CONSTEXPR_FN Base64InverseTable() {
    for (int i = 0; i < 256; i++) {
      table[i] = 255;
    }
    for (const char* p = kBase64Alphabet; *p; p++) {
      uint8_t idx = *p;
      uint8_t ofs = p - kBase64Alphabet;
      table[idx] = ofs;
    }
  }
};

static GRPC_HPACK_CONSTEXPR_VALUE Base64InverseTable kBase64InverseTable;
}  // namespace

void HPackParser::FinishFrame() {
  sink_ = Sink();
  dynamic_table_updates_allowed_ = 2;
}

void GPR_ATTRIBUTE_NOINLINE HPackParser::LogHeader(grpc_mdelem md) {
  char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
  char* v = nullptr;
  if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
    v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
  } else {
    v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
  }
  gpr_log(
      GPR_INFO,
      "Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
      k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
      grpc_slice_is_interned(GRPC_MDKEY(md)),
      grpc_slice_is_interned(GRPC_MDVALUE(md)));
  gpr_free(k);
  gpr_free(v);
}

/* emission helpers */
template <HPackParser::TableAction action>
grpc_error_handle HPackParser::FinishHeader(grpc_mdelem md) {
  if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_hpack_parser)) {
    LogHeader(md);
  }
  if (action == TableAction::kAddToTable) {
    GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
                     GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
    grpc_error_handle err = grpc_chttp2_hptbl_add(&table_, md);
    if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
  }
  return sink_(md);
}

UnmanagedMemorySlice HPackParser::String::TakeExtern() {
  UnmanagedMemorySlice s;
  if (!copied_) {
    GPR_DEBUG_ASSERT(!grpc_slice_is_interned(data_.referenced));
    s = static_cast<UnmanagedMemorySlice&>(data_.referenced);
    copied_ = true;
    data_.referenced = UnmanagedMemorySlice();
  } else {
    s = UnmanagedMemorySlice(data_.copied.str, data_.copied.length);
  }
  data_.copied.length = 0;
  return s;
}

ManagedMemorySlice HPackParser::String::TakeIntern() {
  ManagedMemorySlice s;
  if (!copied_) {
    s = ManagedMemorySlice(&data_.referenced);
    grpc_slice_unref_internal(data_.referenced);
    copied_ = true;
    data_.referenced = grpc_empty_slice();
  } else {
    s = ManagedMemorySlice(data_.copied.str, data_.copied.length);
  }
  data_.copied.length = 0;
  return s;
}

grpc_error_handle HPackParser::parse_next(const uint8_t* cur,
                                          const uint8_t* end) {
  state_ = *next_state_++;
  return (this->*state_)(cur, end);
}

/* begin parsing a header: all functionality is encoded into lookup tables
   above */
grpc_error_handle HPackParser::parse_begin(const uint8_t* cur,
                                           const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_begin;
    return GRPC_ERROR_NONE;
  }

  switch (*cur >> 4) {
      // Literal header not indexed.
      // First byte format: 0000xxxx
      // Where xxxx:
      //   0000  - literal key
      //   1111  - indexed key, varint encoded index
      //   other - indexed key, inline encoded index
    case 0:
      switch (*cur & 0xf) {
        case 0:  // literal key
          return parse_lithdr_notidx_v(cur, end);
        case 0xf:  // varint encoded key index
          return parse_lithdr_notidx_x(cur, end);
        default:  // inline encoded key index
          return parse_lithdr_notidx(cur, end);
      }
      // Literal header never indexed.
      // First byte format: 0001xxxx
      // Where xxxx:
      //   0000  - literal key
      //   1111  - indexed key, varint encoded index
      //   other - indexed key, inline encoded index
    case 1:
      switch (*cur & 0xf) {
        case 0:  // literal key
          return parse_lithdr_nvridx_v(cur, end);
        case 0xf:  // varint encoded key index
          return parse_lithdr_nvridx_x(cur, end);
        default:  // inline encoded key index
          return parse_lithdr_nvridx(cur, end);
      }
      // Update max table size.
      // First byte format: 001xxxxx
      // Where xxxxx:
      //   11111 - max size is varint encoded
      //   other - max size is stored inline
    case 2:
      // inline encoded max table size
      return parse_max_tbl_size(cur, end);
    case 3:
      if (*cur == 0x3f) {
        // varint encoded max table size
        return parse_max_tbl_size_x(cur, end);
      } else {
        // inline encoded max table size
        return parse_max_tbl_size(cur, end);
      }
      // Literal header with incremental indexing.
      // First byte format: 01xxxxxx
      // Where xxxxxx:
      //   000000 - literal key
      //   111111 - indexed key, varint encoded index
      //   other  - indexed key, inline encoded index
    case 4:
      if (*cur == 0x40) {
        // literal key
        return parse_lithdr_incidx_v(cur, end);
      }
    case 5:
    case 6:
      // inline encoded key index
      return parse_lithdr_incidx(cur, end);
    case 7:
      if (*cur == 0x7f) {
        // varint encoded key index
        return parse_lithdr_incidx_x(cur, end);
      } else {
        // inline encoded key index
        return parse_lithdr_incidx(cur, end);
      }
      // Indexed Header Field Representation
      // First byte format: 1xxxxxxx
      // Where xxxxxxx:
      //   0000000 - illegal
      //   1111111 - varint encoded field index
      //   other   - inline encoded field index
    case 8:
      if (*cur == 0x80) {
        // illegal value.
        return parse_illegal_op(cur, end);
      }
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
      // inline encoded field index
      return parse_indexed_field(cur, end);
    case 15:
      if (*cur == 0xff) {
        // varint encoded field index
        return parse_indexed_field_x(cur, end);
      } else {
        // inline encoded field index
        return parse_indexed_field(cur, end);
      }
  }
  GPR_UNREACHABLE_CODE(abort());
}

/* stream dependency and prioritization data: we just skip it */
grpc_error_handle HPackParser::parse_stream_weight(const uint8_t* cur,
                                                   const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_stream_weight;
    return GRPC_ERROR_NONE;
  }

  return (this->*after_prioritization_)(cur + 1, end);
}

grpc_error_handle HPackParser::parse_stream_dep3(const uint8_t* cur,
                                                 const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_stream_dep3;
    return GRPC_ERROR_NONE;
  }

  return parse_stream_weight(cur + 1, end);
}

grpc_error_handle HPackParser::parse_stream_dep2(const uint8_t* cur,
                                                 const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_stream_dep2;
    return GRPC_ERROR_NONE;
  }

  return parse_stream_dep3(cur + 1, end);
}

grpc_error_handle HPackParser::parse_stream_dep1(const uint8_t* cur,
                                                 const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_stream_dep1;
    return GRPC_ERROR_NONE;
  }

  return parse_stream_dep2(cur + 1, end);
}

grpc_error_handle HPackParser::parse_stream_dep0(const uint8_t* cur,
                                                 const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_stream_dep0;
    return GRPC_ERROR_NONE;
  }

  return parse_stream_dep1(cur + 1, end);
}

grpc_error_handle HPackParser::InvalidHPackIndexError() {
  return grpc_error_set_int(
      grpc_error_set_int(
          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid HPACK index received"),
          GRPC_ERROR_INT_INDEX, static_cast<intptr_t>(index_)),
      GRPC_ERROR_INT_SIZE, static_cast<intptr_t>(table_.num_ents));
}

/* emit an indexed field; jumps to begin the next field on completion */
grpc_error_handle HPackParser::finish_indexed_field(const uint8_t* cur,
                                                    const uint8_t* end) {
  grpc_mdelem md = grpc_chttp2_hptbl_lookup<true>(&table_, index_);
  if (GPR_UNLIKELY(GRPC_MDISNULL(md))) {
    return InvalidHPackIndexError();
  }
  GRPC_STATS_INC_HPACK_RECV_INDEXED();
  grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(md);
  if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
  return parse_begin(cur, end);
}

/* parse an indexed field with index < 127 */
grpc_error_handle HPackParser::parse_indexed_field(const uint8_t* cur,
                                                   const uint8_t* end) {
  dynamic_table_updates_allowed_ = 0;
  index_ = (*cur) & 0x7f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  return finish_indexed_field(cur + 1, end);
}

/* parse an indexed field with index >= 127 */
grpc_error_handle HPackParser::parse_indexed_field_x(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {&HPackParser::finish_indexed_field};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = 0x7f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  parsing_.value = &index_;
  return parse_value0(cur + 1, end);
}

/* When finishing with a header, get the cached md element for this index.
   This is set in parse_value_string(). We ensure (in debug mode) that the
   cached metadata corresponds with the index we are examining. */
grpc_mdelem HPackParser::GetPrecomputedMDForIndex() {
  GPR_DEBUG_ASSERT(md_for_index_.payload != 0);
  GPR_DEBUG_ASSERT(static_cast<int64_t>(index_) == precomputed_md_index_);
  grpc_mdelem md = md_for_index_;
  GPR_DEBUG_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
#ifndef NDEBUG
  precomputed_md_index_ = -1;
#endif
  return md;
}

static const grpc_core::ManagedMemorySlice& get_indexed_key(grpc_mdelem md) {
  GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(md));
  return static_cast<const grpc_core::ManagedMemorySlice&>(
      grpc_slice_ref_internal(GRPC_MDKEY(md)));
}

/* finish a literal header with incremental indexing */
grpc_error_handle HPackParser::finish_lithdr_incidx(const uint8_t* cur,
                                                    const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX();
  grpc_mdelem md = GetPrecomputedMDForIndex();
  grpc_error_handle err = FinishHeader<TableAction::kAddToTable>(
      grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeIntern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* finish a literal header with incremental indexing with no index */
grpc_error_handle HPackParser::finish_lithdr_incidx_v(const uint8_t* cur,
                                                      const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V();
  grpc_error_handle err = FinishHeader<TableAction::kAddToTable>(
      grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeIntern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* parse a literal header with incremental indexing; index < 63 */
grpc_error_handle HPackParser::parse_lithdr_incidx(const uint8_t* cur,
                                                   const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_incidx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = (*cur) & 0x3f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  return parse_string_prefix(cur + 1, end);
}

/* parse a literal header with incremental indexing; index >= 63 */
grpc_error_handle HPackParser::parse_lithdr_incidx_x(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_incidx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = 0x3f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  parsing_.value = &index_;
  return parse_value0(cur + 1, end);
}

/* parse a literal header with incremental indexing; index = 0 */
grpc_error_handle HPackParser::parse_lithdr_incidx_v(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_literal_key,
      &HPackParser::finish_lithdr_incidx_v};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  return parse_string_prefix(cur + 1, end);
}

/* finish a literal header without incremental indexing */
grpc_error_handle HPackParser::finish_lithdr_notidx(const uint8_t* cur,
                                                    const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX();
  grpc_mdelem md = GetPrecomputedMDForIndex();
  grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
      grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeExtern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* finish a literal header without incremental indexing with index = 0 */
grpc_error_handle HPackParser::finish_lithdr_notidx_v(const uint8_t* cur,
                                                      const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V();
  grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
      grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeExtern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* parse a literal header without incremental indexing; index < 15 */
grpc_error_handle HPackParser::parse_lithdr_notidx(const uint8_t* cur,
                                                   const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_notidx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = (*cur) & 0xf;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  return parse_string_prefix(cur + 1, end);
}

/* parse a literal header without incremental indexing; index >= 15 */
grpc_error_handle HPackParser::parse_lithdr_notidx_x(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_notidx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = 0xf;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  parsing_.value = &index_;
  return parse_value0(cur + 1, end);
}

/* parse a literal header without incremental indexing; index == 0 */
grpc_error_handle HPackParser::parse_lithdr_notidx_v(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_literal_key,
      &HPackParser::finish_lithdr_notidx_v};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  return parse_string_prefix(cur + 1, end);
}

/* finish a literal header that is never indexed */
grpc_error_handle HPackParser::finish_lithdr_nvridx(const uint8_t* cur,
                                                    const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX();
  grpc_mdelem md = GetPrecomputedMDForIndex();
  grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
      grpc_mdelem_from_slices(get_indexed_key(md), value_.TakeExtern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* finish a literal header that is never indexed with an extra value */
grpc_error_handle HPackParser::finish_lithdr_nvridx_v(const uint8_t* cur,
                                                      const uint8_t* end) {
  GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V();
  grpc_error_handle err = FinishHeader<TableAction::kOmitFromTable>(
      grpc_mdelem_from_slices(key_.TakeIntern(), value_.TakeExtern()));
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* parse a literal header that is never indexed; index < 15 */
grpc_error_handle HPackParser::parse_lithdr_nvridx(const uint8_t* cur,
                                                   const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_nvridx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = (*cur) & 0xf;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  return parse_string_prefix(cur + 1, end);
}

/* parse a literal header that is never indexed; index >= 15 */
grpc_error_handle HPackParser::parse_lithdr_nvridx_x(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_indexed_key,
      &HPackParser::finish_lithdr_nvridx};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  index_ = 0xf;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  parsing_.value = &index_;
  return parse_value0(cur + 1, end);
}

/* parse a literal header that is never indexed; index == 0 */
grpc_error_handle HPackParser::parse_lithdr_nvridx_v(const uint8_t* cur,
                                                     const uint8_t* end) {
  static const State and_then[] = {
      &HPackParser::parse_key_string, &HPackParser::parse_string_prefix,
      &HPackParser::parse_value_string_with_literal_key,
      &HPackParser::finish_lithdr_nvridx_v};
  dynamic_table_updates_allowed_ = 0;
  next_state_ = and_then;
  return parse_string_prefix(cur + 1, end);
}

/* finish parsing a max table size change */
grpc_error_handle HPackParser::finish_max_tbl_size(const uint8_t* cur,
                                                   const uint8_t* end) {
  if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_hpack_parser)) {
    gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", index_);
  }
  grpc_error_handle err =
      grpc_chttp2_hptbl_set_current_table_size(&table_, index_);
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_begin(cur, end);
}

/* parse a max table size change, max size < 15 */
grpc_error_handle HPackParser::parse_max_tbl_size(const uint8_t* cur,
                                                  const uint8_t* end) {
  if (dynamic_table_updates_allowed_ == 0) {
    return parse_error(
        cur, end,
        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
            "More than two max table size changes in a single frame"));
  }
  dynamic_table_updates_allowed_--;
  index_ = (*cur) & 0x1f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  return finish_max_tbl_size(cur + 1, end);
}

/* parse a max table size change, max size >= 15 */
grpc_error_handle HPackParser::parse_max_tbl_size_x(const uint8_t* cur,
                                                    const uint8_t* end) {
  static const State and_then[] = {&HPackParser::finish_max_tbl_size};
  if (dynamic_table_updates_allowed_ == 0) {
    return parse_error(
        cur, end,
        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
            "More than two max table size changes in a single frame"));
  }
  dynamic_table_updates_allowed_--;
  next_state_ = and_then;
  index_ = 0x1f;
  md_for_index_.payload = 0; /* Invalidate cached md when index changes. */
  parsing_.value = &index_;
  return parse_value0(cur + 1, end);
}

/* a parse error: jam the parse state into parse_error, and return error */
grpc_error_handle HPackParser::parse_error(const uint8_t* /*cur*/,
                                           const uint8_t* /*end*/,
                                           grpc_error_handle err) {
  GPR_ASSERT(err != GRPC_ERROR_NONE);
  if (last_error_ == GRPC_ERROR_NONE) {
    last_error_ = GRPC_ERROR_REF(err);
  }
  state_ = &HPackParser::still_parse_error;
  return err;
}

grpc_error_handle HPackParser::still_parse_error(const uint8_t* /*cur*/,
                                                 const uint8_t* /*end*/) {
  return GRPC_ERROR_REF(last_error_);
}

grpc_error_handle HPackParser::parse_illegal_op(const uint8_t* cur,
                                                const uint8_t* end) {
  GPR_ASSERT(cur != end);
  grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
      absl::StrCat("Illegal hpack op code ", *cur).c_str());
  return parse_error(cur, end, err);
}

/* parse the 1st byte of a varint into parsing_.value
   no overflow is possible */
grpc_error_handle HPackParser::parse_value0(const uint8_t* cur,
                                            const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_value0;
    return GRPC_ERROR_NONE;
  }

  *parsing_.value += (*cur) & 0x7f;

  if ((*cur) & 0x80) {
    return parse_value1(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }
}

/* parse the 2nd byte of a varint into parsing_.value
   no overflow is possible */
grpc_error_handle HPackParser::parse_value1(const uint8_t* cur,
                                            const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_value1;
    return GRPC_ERROR_NONE;
  }

  *parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 7;

  if ((*cur) & 0x80) {
    return parse_value2(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }
}

/* parse the 3rd byte of a varint into parsing_.value
   no overflow is possible */
grpc_error_handle HPackParser::parse_value2(const uint8_t* cur,
                                            const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_value2;
    return GRPC_ERROR_NONE;
  }

  *parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 14;

  if ((*cur) & 0x80) {
    return parse_value3(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }
}

/* parse the 4th byte of a varint into parsing_.value
   no overflow is possible */
grpc_error_handle HPackParser::parse_value3(const uint8_t* cur,
                                            const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_value3;
    return GRPC_ERROR_NONE;
  }

  *parsing_.value += ((static_cast<uint32_t>(*cur)) & 0x7f) << 21;

  if ((*cur) & 0x80) {
    return parse_value4(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }
}

/* parse the 5th byte of a varint into parsing_.value
   depending on the byte, we may overflow, and care must be taken */
grpc_error_handle HPackParser::parse_value4(const uint8_t* cur,
                                            const uint8_t* end) {
  uint8_t c;
  uint32_t cur_value;
  uint32_t add_value;

  if (cur == end) {
    state_ = &HPackParser::parse_value4;
    return GRPC_ERROR_NONE;
  }

  c = (*cur) & 0x7f;
  if (c > 0xf) {
    goto error;
  }

  cur_value = *parsing_.value;
  add_value = (static_cast<uint32_t>(c)) << 28;
  if (add_value > 0xffffffffu - cur_value) {
    goto error;
  }

  *parsing_.value = cur_value + add_value;

  if ((*cur) & 0x80) {
    return parse_value5up(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }

error:
  grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
      absl::StrFormat(
          "integer overflow in hpack integer decoding: have 0x%08x, "
          "got byte 0x%02x on byte 5",
          *parsing_.value, *cur)
          .c_str());
  return parse_error(cur, end, err);
}

/* parse any trailing bytes in a varint: it's possible to append an arbitrary
   number of 0x80's and not affect the value - a zero will terminate - and
   anything else will overflow */
grpc_error_handle HPackParser::parse_value5up(const uint8_t* cur,
                                              const uint8_t* end) {
  while (cur != end && *cur == 0x80) {
    ++cur;
  }

  if (cur == end) {
    state_ = &HPackParser::parse_value5up;
    return GRPC_ERROR_NONE;
  }

  if (*cur == 0) {
    return parse_next(cur + 1, end);
  }

  grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
      absl::StrFormat(
          "integer overflow in hpack integer decoding: have 0x%08x, "
          "got byte 0x%02x sometime after byte 5",
          *parsing_.value, *cur)
          .c_str());
  return parse_error(cur, end, err);
}

/* parse a string prefix */
grpc_error_handle HPackParser::parse_string_prefix(const uint8_t* cur,
                                                   const uint8_t* end) {
  if (cur == end) {
    state_ = &HPackParser::parse_string_prefix;
    return GRPC_ERROR_NONE;
  }

  strlen_ = (*cur) & 0x7f;
  huff_ = (*cur) >> 7;
  if (strlen_ == 0x7f) {
    parsing_.value = &strlen_;
    return parse_value0(cur + 1, end);
  } else {
    return parse_next(cur + 1, end);
  }
}

/* append some bytes to a string */
void HPackParser::String::AppendBytes(const uint8_t* data, size_t length) {
  if (length == 0) return;
  if (length + data_.copied.length > data_.copied.capacity) {
    GPR_ASSERT(data_.copied.length + length <= UINT32_MAX);
    data_.copied.capacity = static_cast<uint32_t>(data_.copied.length + length);
    data_.copied.str = static_cast<char*>(
        gpr_realloc(data_.copied.str, data_.copied.capacity));
  }
  memcpy(data_.copied.str + data_.copied.length, data, length);
  GPR_ASSERT(length <= UINT32_MAX - data_.copied.length);
  data_.copied.length += static_cast<uint32_t>(length);
}

grpc_error_handle HPackParser::AppendString(const uint8_t* cur,
                                            const uint8_t* end) {
  String* str = parsing_.str;
  uint32_t bits;
  uint8_t decoded[3];
  switch (binary_) {
    case BinaryState::kNotBinary:
      str->AppendBytes(cur, static_cast<size_t>(end - cur));
      return GRPC_ERROR_NONE;
    case BinaryState::kBinaryBegin:
      if (cur == end) {
        binary_ = BinaryState::kBinaryBegin;
        return GRPC_ERROR_NONE;
      }
      if (*cur == 0) {
        /* 'true-binary' case */
        ++cur;
        binary_ = BinaryState::kNotBinary;
        GRPC_STATS_INC_HPACK_RECV_BINARY();
        str->AppendBytes(cur, static_cast<size_t>(end - cur));
        return GRPC_ERROR_NONE;
      }
      GRPC_STATS_INC_HPACK_RECV_BINARY_BASE64();
    /* fallthrough */
    b64_byte0:
    case BinaryState::kBase64Byte0:
      if (cur == end) {
        binary_ = BinaryState::kBase64Byte0;
        return GRPC_ERROR_NONE;
      }
      bits = kBase64InverseTable.table[*cur];
      ++cur;
      if (bits == 255) {
        return parse_error(
            cur, end,
            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
      } else if (bits == 64) {
        goto b64_byte0;
      }
      base64_buffer_ = bits << 18;
    /* fallthrough */
    b64_byte1:
    case BinaryState::kBase64Byte1:
      if (cur == end) {
        binary_ = BinaryState::kBase64Byte1;
        return GRPC_ERROR_NONE;
      }
      bits = kBase64InverseTable.table[*cur];
      ++cur;
      if (bits == 255) {
        return parse_error(
            cur, end,
            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
      } else if (bits == 64) {
        goto b64_byte1;
      }
      base64_buffer_ |= bits << 12;
    /* fallthrough */
    b64_byte2:
    case BinaryState::kBase64Byte2:
      if (cur == end) {
        binary_ = BinaryState::kBase64Byte2;
        return GRPC_ERROR_NONE;
      }
      bits = kBase64InverseTable.table[*cur];
      ++cur;
      if (bits == 255) {
        return parse_error(
            cur, end,
            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
      } else if (bits == 64) {
        goto b64_byte2;
      }
      base64_buffer_ |= bits << 6;
    /* fallthrough */
    b64_byte3:
    case BinaryState::kBase64Byte3:
      if (cur == end) {
        binary_ = BinaryState::kBase64Byte3;
        return GRPC_ERROR_NONE;
      }
      bits = kBase64InverseTable.table[*cur];
      ++cur;
      if (bits == 255) {
        return parse_error(
            cur, end,
            GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character"));
      } else if (bits == 64) {
        goto b64_byte3;
      }
      base64_buffer_ |= bits;
      bits = base64_buffer_;
      decoded[0] = static_cast<uint8_t>(bits >> 16);
      decoded[1] = static_cast<uint8_t>(bits >> 8);
      decoded[2] = static_cast<uint8_t>(bits);
      str->AppendBytes(decoded, 3);
      goto b64_byte0;
  }
  GPR_UNREACHABLE_CODE(return parse_error(
      cur, end,
      GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here")));
}

grpc_error_handle HPackParser::finish_str(const uint8_t* cur,
                                          const uint8_t* end) {
  uint8_t decoded[2];
  uint32_t bits;
  String* str = parsing_.str;
  switch (binary_) {
    case BinaryState::kNotBinary:
      break;
    case BinaryState::kBinaryBegin:
      break;
    case BinaryState::kBase64Byte0:
      break;
    case BinaryState::kBase64Byte1:
      return parse_error(cur, end,
                         GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                             "illegal base64 encoding")); /* illegal encoding */
    case BinaryState::kBase64Byte2:
      bits = base64_buffer_;
      if (bits & 0xffff) {
        grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
            absl::StrFormat("trailing bits in base64 encoding: 0x%04x",
                            bits & 0xffff)
                .c_str());
        return parse_error(cur, end, err);
      }
      decoded[0] = static_cast<uint8_t>(bits >> 16);
      str->AppendBytes(decoded, 1);
      break;
    case BinaryState::kBase64Byte3:
      bits = base64_buffer_;
      if (bits & 0xff) {
        grpc_error_handle err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
            absl::StrFormat("trailing bits in base64 encoding: 0x%02x",
                            bits & 0xff)
                .c_str());
        return parse_error(cur, end, err);
      }
      decoded[0] = static_cast<uint8_t>(bits >> 16);
      decoded[1] = static_cast<uint8_t>(bits >> 8);
      str->AppendBytes(decoded, 2);
      break;
  }
  return GRPC_ERROR_NONE;
}

/* decode a nibble from a huffman encoded stream */
grpc_error_handle HPackParser::AppendHuffNibble(uint8_t nibble) {
  int16_t emit = emit_sub_tbl[16 * emit_tbl[huff_state_] + nibble];
  int16_t next = next_sub_tbl[16 * next_tbl[huff_state_] + nibble];
  if (emit != -1) {
    if (emit >= 0 && emit < 256) {
      uint8_t c = static_cast<uint8_t>(emit);
      grpc_error_handle err = AppendString(&c, (&c) + 1);
      if (err != GRPC_ERROR_NONE) return err;
    } else {
      assert(emit == 256);
    }
  }
  huff_state_ = next;
  return GRPC_ERROR_NONE;
}

/* decode full bytes from a huffman encoded stream */
grpc_error_handle HPackParser::AppendHuffBytes(const uint8_t* cur,
                                               const uint8_t* end) {
  for (; cur != end; ++cur) {
    grpc_error_handle err = AppendHuffNibble(*cur >> 4);
    if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
    err = AppendHuffNibble(*cur & 0xf);
    if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  }
  return GRPC_ERROR_NONE;
}

/* decode some string bytes based on the current decoding mode
   (huffman or not) */
grpc_error_handle HPackParser::AppendStrBytes(const uint8_t* cur,
                                              const uint8_t* end) {
  if (huff_) {
    return AppendHuffBytes(cur, end);
  } else {
    return AppendString(cur, end);
  }
}

/* parse a string - tries to do large chunks at a time */
grpc_error_handle HPackParser::parse_string(const uint8_t* cur,
                                            const uint8_t* end) {
  size_t remaining = strlen_ - strgot_;
  size_t given = static_cast<size_t>(end - cur);
  if (remaining <= given) {
    grpc_error_handle err = AppendStrBytes(cur, cur + remaining);
    if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
    err = finish_str(cur + remaining, end);
    if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
    return parse_next(cur + remaining, end);
  } else {
    grpc_error_handle err = AppendStrBytes(cur, cur + given);
    if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
    GPR_ASSERT(given <= UINT32_MAX - strgot_);
    strgot_ += static_cast<uint32_t>(given);
    state_ = &HPackParser::parse_string;
    return GRPC_ERROR_NONE;
  }
}

/* begin parsing a string - performs setup, calls parse_string */
grpc_error_handle HPackParser::begin_parse_string(const uint8_t* cur,
                                                  const uint8_t* end,
                                                  BinaryState binary,
                                                  HPackParser::String* str) {
  if (!huff_ && binary == BinaryState::kNotBinary &&
      static_cast<uint32_t>(end - cur) >= strlen_ &&
      current_slice_refcount_ != nullptr) {
    GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED();
    str->copied_ = false;
    str->data_.referenced.refcount = current_slice_refcount_;
    str->data_.referenced.data.refcounted.bytes = const_cast<uint8_t*>(cur);
    str->data_.referenced.data.refcounted.length = strlen_;
    grpc_slice_ref_internal(str->data_.referenced);
    return parse_next(cur + strlen_, end);
  }
  strgot_ = 0;
  str->copied_ = true;
  str->data_.copied.length = 0;
  parsing_.str = str;
  huff_state_ = 0;
  binary_ = binary;
  switch (binary_) {
    case BinaryState::kNotBinary:
      if (huff_) {
        GRPC_STATS_INC_HPACK_RECV_HUFFMAN();
      } else {
        GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED();
      }
      break;
    case BinaryState::kBinaryBegin:
      /* stats incremented later: don't know true binary or not */
      break;
    default:
      abort();
  }
  return parse_string(cur, end);
}

/* parse the key string */
grpc_error_handle HPackParser::parse_key_string(const uint8_t* cur,
                                                const uint8_t* end) {
  return begin_parse_string(cur, end, BinaryState::kNotBinary, &key_);
}

/* check if a key represents a binary header or not */

bool HPackParser::IsBinaryLiteralHeader() {
  /* We know that either argument here is a reference counter slice.
   * 1. If it is a grpc_core::StaticSlice, the refcount is set to kNoopRefcount.
   * 2. If it's key_.data.referenced, then key_.copied was set to false,
   *    which occurs in begin_parse_string() - where the refcount is set to
   *    current_slice_refcount_, which is not null. */
  return grpc_is_refcounted_slice_binary_header(
      key_.copied_ ? grpc_core::ExternallyManagedSlice(key_.data_.copied.str,
                                                       key_.data_.copied.length)
                   : key_.data_.referenced);
}

/* Cache the metadata for the given index during initial parsing. This avoids a
   pointless recomputation of the metadata when finishing a header. We read the
   cached value in get_precomputed_md_for_idx(). */
void HPackParser::SetPrecomputedMDIndex(grpc_mdelem md) {
  GPR_DEBUG_ASSERT(md_for_index_.payload == 0);
  GPR_DEBUG_ASSERT(precomputed_md_index_ == -1);
  md_for_index_ = md;
#ifndef NDEBUG
  precomputed_md_index_ = index_;
#endif
}

/* Determines if a metadata element key associated with the current parser index
   is a binary indexed header during string parsing. We'll need to revisit this
   metadata when we're done parsing, so we cache the metadata for this index
   here using set_precomputed_md_idx(). */
grpc_error_handle HPackParser::IsBinaryIndexedHeader(bool* is) {
  grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&table_, index_);
  if (GPR_UNLIKELY(GRPC_MDISNULL(elem))) {
    return InvalidHPackIndexError();
  }
  /* We know that GRPC_MDKEY(elem) points to a reference counted slice since:
   * 1. elem was a result of grpc_chttp2_hptbl_lookup
   * 2. An item in this table is either static (see entries with
   *    index < GRPC_CHTTP2_LAST_STATIC_ENTRY or added via
   *    grpc_chttp2_hptbl_add).
   * 3. If added via grpc_chttp2_hptbl_add, the entry is either static or
   *    interned.
   * 4. Both static and interned element slices have non-null refcounts. */
  *is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem));
  SetPrecomputedMDIndex(elem);
  return GRPC_ERROR_NONE;
}

/* parse the value string */
grpc_error_handle HPackParser::parse_value_string(const uint8_t* cur,
                                                  const uint8_t* end,
                                                  bool is_binary) {
  return begin_parse_string(
      cur, end, is_binary ? BinaryState::kBinaryBegin : BinaryState::kNotBinary,
      &value_);
}

grpc_error_handle HPackParser::parse_value_string_with_indexed_key(
    const uint8_t* cur, const uint8_t* end) {
  bool is_binary = false;
  grpc_error_handle err = IsBinaryIndexedHeader(&is_binary);
  if (err != GRPC_ERROR_NONE) return parse_error(cur, end, err);
  return parse_value_string(cur, end, is_binary);
}

grpc_error_handle HPackParser::parse_value_string_with_literal_key(
    const uint8_t* cur, const uint8_t* end) {
  return parse_value_string(cur, end, IsBinaryLiteralHeader());
}

/* PUBLIC INTERFACE */

HPackParser::HPackParser() {
  state_ = &HPackParser::parse_begin;
  key_.data_.referenced = grpc_empty_slice();
  key_.data_.copied.str = nullptr;
  key_.data_.copied.capacity = 0;
  key_.data_.copied.length = 0;
  value_.data_.referenced = grpc_empty_slice();
  value_.data_.copied.str = nullptr;
  value_.data_.copied.capacity = 0;
  value_.data_.copied.length = 0;
  /* Cached metadata for the current index the parser is handling. This is set
     to 0 initially, invalidated when the index changes, and invalidated when it
     is read (by get_precomputed_md_for_idx()). It is set during string parsing,
     by set_precomputed_md_idx() - which is called by parse_value_string().
     The goal here is to avoid recomputing the metadata for the index when
     finishing with a header as well as the initial parse. */
  md_for_index_.payload = 0;
#ifndef NDEBUG
  /* In debug mode, this ensures that the cached metadata we're reading is in
   * fact correct for the index we are examining. */
  precomputed_md_index_ = -1;
#endif
  dynamic_table_updates_allowed_ = 2;
  last_error_ = GRPC_ERROR_NONE;
}

void HPackParser::BeginFrame(Sink sink, Boundary boundary, Priority priority) {
  sink_ = std::move(sink);
  boundary_ = boundary;
  switch (priority) {
    case Priority::Included:
      after_prioritization_ = state_;
      state_ = &HPackParser::parse_stream_dep0;
      break;
    case Priority::None:
      break;
  }
}

HPackParser::~HPackParser() {
  grpc_chttp2_hptbl_destroy(&table_);
  GRPC_ERROR_UNREF(last_error_);
  grpc_slice_unref_internal(key_.data_.referenced);
  grpc_slice_unref_internal(value_.data_.referenced);
  gpr_free(key_.data_.copied.str);
  gpr_free(value_.data_.copied.str);
}

grpc_error_handle HPackParser::Parse(const grpc_slice& slice) {
/* max number of bytes to parse at a time... limits call stack depth on
 * compilers without TCO */
#define MAX_PARSE_LENGTH 1024
  current_slice_refcount_ = slice.refcount;
  const uint8_t* start = GRPC_SLICE_START_PTR(slice);
  const uint8_t* end = GRPC_SLICE_END_PTR(slice);
  grpc_error_handle error = GRPC_ERROR_NONE;
  while (start != end && error == GRPC_ERROR_NONE) {
    const uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start);
    error = (this->*state_)(start, target);
    start = target;
  }
  current_slice_refcount_ = nullptr;
  return error;
}

}  // namespace grpc_core

// TODO(ctiller): this serves as an eviction notice for the remainder of this
// file... it belongs elsewhere!

typedef void (*maybe_complete_func_type)(grpc_chttp2_transport* t,
                                         grpc_chttp2_stream* s);
static const maybe_complete_func_type maybe_complete_funcs[] = {
    grpc_chttp2_maybe_complete_recv_initial_metadata,
    grpc_chttp2_maybe_complete_recv_trailing_metadata};

static void force_client_rst_stream(void* sp, grpc_error_handle /*error*/) {
  grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(sp);
  grpc_chttp2_transport* t = s->t;
  if (!s->write_closed) {
    grpc_chttp2_add_rst_stream_to_next_write(t, s->id, GRPC_HTTP2_NO_ERROR,
                                             &s->stats.outgoing);
    grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_FORCE_RST_STREAM);
    grpc_chttp2_mark_stream_closed(t, s, true, true, GRPC_ERROR_NONE);
  }
  GRPC_CHTTP2_STREAM_UNREF(s, "final_rst");
}

static void parse_stream_compression_md(grpc_chttp2_transport* /*t*/,
                                        grpc_chttp2_stream* s,
                                        grpc_metadata_batch* initial_metadata) {
  if (initial_metadata->idx.named.content_encoding == nullptr ||
      grpc_stream_compression_method_parse(
          GRPC_MDVALUE(initial_metadata->idx.named.content_encoding->md), false,
          &s->stream_decompression_method) == 0) {
    s->stream_decompression_method =
        GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS;
  }

  if (s->stream_decompression_method !=
      GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) {
    s->stream_decompression_ctx = nullptr;
    grpc_slice_buffer_init(&s->decompressed_data_buffer);
  }
}

grpc_error_handle grpc_chttp2_header_parser_parse(void* hpack_parser,
                                                  grpc_chttp2_transport* t,
                                                  grpc_chttp2_stream* s,
                                                  const grpc_slice& slice,
                                                  int is_last) {
  GPR_TIMER_SCOPE("grpc_chttp2_header_parser_parse", 0);
  auto* parser = static_cast<grpc_core::HPackParser*>(hpack_parser);
  if (s != nullptr) {
    s->stats.incoming.header_bytes += GRPC_SLICE_LENGTH(slice);
  }
  grpc_error_handle error = parser->Parse(slice);
  if (error != GRPC_ERROR_NONE) {
    return error;
  }
  if (is_last) {
    if (parser->is_boundary() && !parser->is_in_begin_state()) {
      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
          "end of header frame not aligned with a hpack record boundary");
    }
    /* need to check for null stream: this can occur if we receive an invalid
       stream id on a header */
    if (s != nullptr) {
      if (parser->is_boundary()) {
        if (s->header_frames_received == GPR_ARRAY_SIZE(s->metadata_buffer)) {
          return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
              "Too many trailer frames");
        }
        /* Process stream compression md element if it exists */
        if (s->header_frames_received ==
            0) { /* Only acts on initial metadata */
          parse_stream_compression_md(t, s, &s->metadata_buffer[0].batch);
        }
        s->published_metadata[s->header_frames_received] =
            GRPC_METADATA_PUBLISHED_FROM_WIRE;
        maybe_complete_funcs[s->header_frames_received](t, s);
        s->header_frames_received++;
      }
      if (parser->is_eof()) {
        if (t->is_client && !s->write_closed) {
          /* server eof ==> complete closure; we may need to forcefully close
             the stream. Wait until the combiner lock is ready to be released
             however -- it might be that we receive a RST_STREAM following this
             and can avoid the extra write */
          GRPC_CHTTP2_STREAM_REF(s, "final_rst");
          t->combiner->FinallyRun(
              GRPC_CLOSURE_CREATE(force_client_rst_stream, s, nullptr),
              GRPC_ERROR_NONE);
        }
        grpc_chttp2_mark_stream_closed(t, s, true, false, GRPC_ERROR_NONE);
      }
    }
    parser->FinishFrame();
  }
  return GRPC_ERROR_NONE;
}
